package vip.ola.manage.code.ctrl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import vip.ola.core.common.Exception.ServiceException;
import vip.ola.core.common.annotation.MethodLog;
import vip.ola.core.common.constant.RetEnum;
import vip.ola.core.common.domain.BizResponse;
import vip.ola.core.common.domain.PayResponse;
import vip.ola.core.common.util.CodeImgUtil;
import vip.ola.core.common.util.MyLog;
import vip.ola.core.common.util.MySeq;
import vip.ola.core.entity.code.CodeInfo;
import vip.ola.manage.common.ctrl.BaseController;
import vip.ola.manage.common.service.RpcCommonService;
import vip.ola.manage.secruity.JwtUser;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;

import static vip.ola.core.common.constant.CodeConstant.*;
import static vip.ola.core.common.constant.Constant.MGR_CONTROLLER_ROOT_PATH;
import static vip.ola.core.common.constant.RetEnum.*;
import static vip.ola.core.common.constant.SysConfigConstant.TYPE_CODE;


@RestController
@RequestMapping(MGR_CONTROLLER_ROOT_PATH + "/code/qr")
public class QrCodeController extends BaseController {

    private final MyLog log = MyLog.getLog(QrCodeController.class);

    @Value("${qr.base-path}")
    private String basePath;
    @Value("${qr.preview-url}")
    private String previewUrl;


    @Autowired
    private RpcCommonService rpcService;

    @RequestMapping("/list")
    public ResponseEntity<?> list(Long codeBusId, LocalTime collStartTime, LocalTime collEndTime, Integer codeType, Integer status,
                                  String username, String collName, String collThirdName, String collThirdAccount, BigDecimal minAmount, BigDecimal maxAmount) {
        CodeInfo codeInfo = new CodeInfo();
        codeInfo.setCodeBusId(codeBusId);
        codeInfo.setCodeType(codeType);
        codeInfo.setStatus(status);
        codeInfo.setUsername(username);
        codeInfo.setCollName(collName);
        codeInfo.setCollThirdName(collName);
        codeInfo.setCollThirdAccount(collThirdAccount);
        codeInfo.setMinAmount(minAmount);
        codeInfo.setMaxAmount(maxAmount);
        codeInfo.setCollStartTime(collStartTime);
        codeInfo.setCollEndTime(collEndTime);
        codeInfo.setDeleted(LOGIC_NOT_DELETE);
        IPage<CodeInfo> page = rpcService.codeInfoService.list(getPageIndex(), getPageSize(), codeInfo);
        return ResponseEntity.ok(PayResponse.buildPageSuccess(page));
    }

    @RequestMapping("/get")
    public ResponseEntity<?> get(long id) {
        CodeInfo codeInfo = rpcService.codeInfoService.getCacheById(id);
        return ResponseEntity.ok(PayResponse.buildSuccess(codeInfo));
    }


    @MethodLog(remark = "添加二维码信息")
    @RequestMapping("/add")
    public ResponseEntity<?> save(CodeInfo code) {
        JwtUser user = getUser();
        code.setUserId(0L);
        code.setUsername(user.getUsername());
        code.setCreateId(getUser().getId());
        code.setCreateTime(LocalDateTime.now());
        boolean isOk = rpcService.codeInfoService.save(code);
        return ResponseEntity.ok(BizResponse.build(isOk));
    }

    @MethodLog(remark = "编辑二维码信息")
    @RequestMapping("/edit")
    public ResponseEntity edit(CodeInfo code) {
        JSONObject json = rpcService.rpcSysConfigService.getSysConfigObj(TYPE_CODE);
        ResponseEntity validate = validate(code, false);
        if (validate != null) {
            return validate;
        }
        code.setWeight(null);
        code.setUpdateTime(LocalDateTime.now());
        boolean isOk = rpcService.codeInfoService.updateById(code);
        return ResponseEntity.ok(BizResponse.build(isOk));
    }

    private ResponseEntity validate(CodeInfo codeInfo,  boolean isAdd) {
        String codePath = request.getParameter("codePath");
        if (StringUtils.isBlank(codePath)) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.CODE_NOT_QRCODE_ERROR));
        }
        String context;
        try {
            context = CodeImgUtil.decodeByPath(basePath + codePath);
        } catch (FileNotFoundException e) {
            log.error("解析二维码出错, path: " + basePath + codePath, e);
            return ResponseEntity.ok(BizResponse.build(CODE_QRCODE_NOT_EXIST));
        }
        if (StringUtils.isBlank(context)) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.CODE_QRCODE_ERROR));
        }
        if(isAdd){
            CodeInfo byCodeUrl = rpcService.codeInfoService.getByCodeUrl(context);
            if (byCodeUrl != null) {
                return ResponseEntity.ok(BizResponse.build(RetEnum.CODE_QRCODE_ALREADY_EXIST));
            }
        }
        codeInfo.setCodeUrl(context);
        codeInfo.setCodePath(codePath);
        return null;
    }

    @RequestMapping("/disable")
    @MethodLog(remark = "停用二维码")
    public ResponseEntity disable(long id) {
        CodeInfo codeInfo = new CodeInfo();
        codeInfo.setId(id);
        codeInfo = rpcService.codeInfoService.getByCodeInfo(codeInfo);
        if (codeInfo == null) {
            return ResponseEntity.ok(BizResponse.build(CODE_QRCODE_NOT_OPERATE));
        }
        if (!CODE_STATUS_OK.equals(codeInfo.getStatus())) {
            return ResponseEntity.ok(BizResponse.build(CODE_QRCODE_STATUS_ERROR));
        }
        boolean isOk = rpcService.codeInfoService.updateStatus(id, CODE_STATUS_STOP);
        return ResponseEntity.ok(BizResponse.build(isOk));
    }

    @RequestMapping("/enable")
    @MethodLog(remark = "启用二维码")
    public ResponseEntity enable(long id) {
        CodeInfo codeInfo = new CodeInfo();
        codeInfo.setId(id);
        codeInfo = rpcService.codeInfoService.getByCodeInfo(codeInfo);
        if (codeInfo == null) {
            return ResponseEntity.ok(BizResponse.build(CODE_QRCODE_NOT_OPERATE));
        }
        if (!CODE_STATUS_STOP.equals(codeInfo.getStatus())) {
            return ResponseEntity.ok(BizResponse.build(CODE_QRCODE_STATUS_ERROR));
        }
        boolean isOk = rpcService.codeInfoService.updateStatus(id, CODE_STATUS_OK);
        return ResponseEntity.ok(BizResponse.build(isOk));
    }

    @RequestMapping("/del")
    @MethodLog(remark = "删除二维码")
    public ResponseEntity del(long id) {
        CodeInfo codeInfo = new CodeInfo();
        codeInfo.setId(id);
        codeInfo = rpcService.codeInfoService.getByCodeInfo(codeInfo);
        if (codeInfo == null) {
            return ResponseEntity.ok(BizResponse.build(CODE_QRCODE_NOT_OPERATE));
        }
        boolean isOk = rpcService.codeInfoService.removeById(id);
        return ResponseEntity.ok(BizResponse.build(isOk));
    }


    @MethodLog(remark = "上传二维码")
    @RequestMapping("/upload")
    public ResponseEntity<?> uploadFile(@RequestParam(value = "file") MultipartFile upFile) {
        if (upFile.isEmpty()) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_COMM_OPERATION_FAIL));
        }
        try {
            long allowMaxSize = 1 * 1024 * 1024;
            if (allowMaxSize < upFile.getSize()) {
                return ResponseEntity.ok(BizResponse.build(RetEnum.CODE_QRCODE_SIZE_ERROR));
            }
            boolean isImage = CodeImgUtil.isImage(upFile.getInputStream());
            if (!isImage) {
                return ResponseEntity.ok(BizResponse.build(RetEnum.CODE_IMG_ERROR));
            }
            String context = CodeImgUtil.decodeByStream(upFile.getInputStream());
            if (StringUtils.isBlank(context)) {
                return ResponseEntity.ok(BizResponse.build(RetEnum.CODE_QRCODE_ERROR));
            }
            CodeInfo byCodeUrl = rpcService.codeInfoService.getByCodeUrl(context);
            if (byCodeUrl != null) {
                return ResponseEntity.ok(BizResponse.build(RetEnum.CODE_QRCODE_ALREADY_EXIST));
            }
            String fileName = upFile.getOriginalFilename();
            String ext = fileName.substring(fileName.lastIndexOf("."));
            String saveName = (MySeq.getUUID() + ext).toLowerCase();
            FileUtils.copyInputStreamToFile(upFile.getInputStream(), new File(basePath + saveName));
            // 返回数据
            Map<String, String> retMap = new HashMap<>(2);
            retMap.put("codePath", saveName);
            retMap.put("url", previewUrl + saveName);
            return ResponseEntity.ok(PayResponse.buildSuccess(retMap));
        } catch (ServiceException e) {
            log.error("商户ID:" + getUser().getId() + "," + e.getRetEnum().getMessage());
            return ResponseEntity.ok(BizResponse.build(e.getRetEnum()));
        } catch (IOException e) {
            log.error(e, "上传文件异常");
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_COMM_UNKNOWN_ERROR));
        }
    }

    @RequestMapping("/view")
    public ResponseEntity view(long id) {
        String codeUrl = rpcService.codeInfoService.getCodeUrlByCache(id);
        return ResponseEntity.ok(PayResponse.buildSuccess(codeUrl));
    }

}
